/* @flow */

import config from '../config'
import { ASSET_TYPES } from 'shared/constants'
import { warn, isPlainObject } from '../util/index'

export function initAssetRegisters (Vue: GlobalAPI) {
  /**
   * Create asset registration methods.
   */
  // export const ASSET_TYPES = [
  //   'component',
  //   'directive',
  //   'filter'
  // ]
  ASSET_TYPES.forEach(type => {
    Vue[type] = function (
      id: string,
      definition: Function | Object
    ): Function | Object | void {
      if (!definition) {
        return this.options[type + 's'][id]
      } else {
        /* istanbul ignore if */
        if (process.env.NODE_ENV !== 'production') {
          if (type === 'component' && config.isReservedTag(id)) {
            warn(
              'Do not use built-in or reserved HTML elements as component ' +
              'id: ' + id
            )
          }
        }
        // 判断类型是组件且第二个参数是原始的 object 对象
        if (type === 'component' && isPlainObject(definition)) {
          // 设置 name  如果传入的对象存在 name 则将 name 作为 name，否则将 id 作为 name
          definition.name = definition.name || id
          // this.options._base 就是 Vue 构造函数  就是相当于 Vue.extend()
          // 把组件配置转换为组件的构造函数 
          definition = this.options._base.extend(definition)
        }
        // 判断类型是指令且是第二个参数是方法
        if (type === 'directive' && typeof definition === 'function') {
          // 修改为对象，并为对象添加 bind 和 updata 方法
          definition = { bind: definition, update: definition }
        }

        // 全局注册，存储资源并赋值
        // 最终都会存在 options.components ... 下面
        this.options[type + 's'][id] = definition
        return definition
      }
    }
  })
}
